package com.android.nodejs.livejs.activities;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketTimeoutException;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;

import org.json.JSONException;
import org.json.JSONObject;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.android.nodejs.livejs.MyApplication;
import com.android.nodejs.livejs.R;
import com.android.nodejs.livejs.constants.AddMessageConstants;
import com.android.nodejs.livejs.constants.ConnectionConstants;
import com.android.nodejs.livejs.constants.DisplayConstants;
import com.android.nodejs.livejs.models.MyMessage;
import com.android.nodejs.livejs.models.User;
import com.android.nodejs.livejs.utils.CommonUtil;

public class SignInActivity extends Activity implements OnItemSelectedListener {

    private EditText edtEmail;
    private EditText edtPassword;
    private Spinner spStatus;
    private CheckBox cbRememberMe;

    private Socket socket = null;
    private InputStream is = null;
    private OutputStream os = null;

    private ProgressDialog progressDialog;

    private String strServerResponse = "";
    private SharedPreferences sp;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        this.requestWindowFeature(Window.FEATURE_NO_TITLE);
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_sign_in);
        sp = getApplicationContext().getSharedPreferences("MySharepreference", Activity.MODE_PRIVATE);
        if(sp.getBoolean("is_remember", false)) {
            MyApplication.USER_CURRENT = new User();
            MyApplication.USER_CURRENT.setId(sp.getInt("id", 0));
            MyApplication.USER_CURRENT.setFullName(sp.getString("full_name", ""));
            MyApplication.USER_CURRENT.setEmail(sp.getString("email", ""));
            MyApplication.USER_CURRENT.setPassword(sp.getString("password", ""));
            MyApplication.USER_CURRENT.setBirthday(sp.getString("birthday", ""));
            MyApplication.USER_CURRENT.setGender(sp.getInt("gender", 0));
            MyApplication.USER_CURRENT.setStatus(sp.getString("status", ""));
            MyApplication.USER_CURRENT.setLastStatus(sp.getString("last_status", ""));
            // set list friends to global variable in MyApplication
            //MyApplication.LIST_FRIENDS = sp.getString("list_friends", "");
            // finish SignInActivity
            finish();
            // start MainActivity
            Intent intentMain = new Intent();
            intentMain.setClass(getApplicationContext(), MainActivity.class);
            startActivity(intentMain);
        }
        edtEmail = (EditText) findViewById(R.id.edtEmail);
        edtEmail.setText("thaivu@gmail.com");
        edtPassword = (EditText) findViewById(R.id.edtPassword);
        edtPassword.setText("1");
        cbRememberMe = (CheckBox) findViewById(R.id.cbRememberMe);

        spStatus = (Spinner) findViewById(R.id.spStatus);
        spStatus.setOnItemSelectedListener(this);
        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(this, R.array.array_status,
                android.R.layout.simple_spinner_item);
        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        spStatus.setAdapter(adapter);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_sign_in, menu);
        return true;
    }

    public void onClickSignUp(View v) {
         Intent signUp = new Intent(this, SignUpActivity.class);
         startActivity(signUp);
    }

    public void onClickSignIn(View v) {
        if ("".equals(edtEmail.getText().toString().trim()) || "".equals(edtPassword.getText().toString().trim())) {
            Toast.makeText(this, "Please fill all fields!", Toast.LENGTH_LONG).show();
        } else if (!checkValidateEmail(edtEmail.getText().toString())) {
            Toast.makeText(this, "Wrong email address format!", Toast.LENGTH_LONG).show();
        } else {
            progressDialog = ProgressDialog.show(this, "", "Signing in...");
            new Thread(new Runnable() {
                public void run() {
                    try {
                        SocketAddress sockAddr = new InetSocketAddress(ConnectionConstants.IP, ConnectionConstants.PORT);
                        socket = new Socket();
                        int timeoutMs = 20000;
                        socket.connect(sockAddr, timeoutMs);
                        is = socket.getInputStream();
                        os = socket.getOutputStream();
                        if (os == null) {
                            if (progressDialog.isShowing()) {
                                progressDialog.dismiss();
                            }
                            return;
                        }
                        BufferedWriter w = new BufferedWriter(new OutputStreamWriter(os));
                        w.write(AddMessageConstants.SIGN_IN);
                        w.write(edtEmail.getText().toString().trim() + "!!"
                                + CommonUtil.convertToMD5(edtPassword.getText().toString().trim()) + "!!"
                                + spStatus.getSelectedItem().toString());
                        w.flush();

                        MessageHanlder messageHanlder = new MessageHanlder();
                        messageHanlder.start();

                        if (progressDialog.isShowing()) {
                            progressDialog.dismiss();
                        }
                    } catch (SocketTimeoutException e) {
                        if (progressDialog.isShowing()) {
                            progressDialog.dismiss();
                        }
                        Message msg = toastHandler.obtainMessage(3);
                        toastHandler.sendMessage(msg);
                        return;
                    } catch (UnknownHostException e) {
                        Log.d("UnknownHostException", e.getClass().getSimpleName() + ": " + e.getMessage());
                        e.printStackTrace();
                    } catch (IOException e) {
                        Log.d("IOException", e.getClass().getSimpleName() + ": " + e.getMessage());
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }

    public void onClickCancel(View v) {
        setResult(RESULT_CANCELED);
        finish();
    }

    public void onClickForgotPassword(View v) {
        Intent forgot = new Intent(this, ForgotPasswordActivity.class);
        startActivity(forgot);
    }

    /**
     * check validate email address format
     * 
     * @param email_address
     * @return true if valid, false if invalid
     */
    public boolean checkValidateEmail(String email_address) {
        return email_address.matches("^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@" + "[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$");
    }

    public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // nothing
    }

    public void onNothingSelected(AdapterView<?> arg0) {
        // nothing
    }

    /** Show Toast message */
    private Handler toastHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            if (msg.what == 0) {
                Toast.makeText(getApplicationContext(), DisplayConstants.DIS_NOT_EXIST_ACCOUNT, Toast.LENGTH_LONG).show();
            } else if (msg.what == 1) {
                Toast.makeText(getApplicationContext(), DisplayConstants.DIS_WRONG_PASSWORD, Toast.LENGTH_LONG).show();
            } else if (msg.what == 2) {
                Toast.makeText(getApplicationContext(), DisplayConstants.DIS_SIGNED_IN, Toast.LENGTH_LONG).show();
            } else if (msg.what == 3) {
                CommonUtil.dialogNotify(SignInActivity.this, DisplayConstants.DIS_CONNECT_SERVER_FAIL);
            }
        }
    };

    /**
     * get message from server response
     * 
     * @author vuvt
     * 
     */
    private class MessageHanlder extends Thread {
        @Override
        public void run() {
            BufferedReader r = new BufferedReader(new InputStreamReader(is));
            try {
                StringBuffer b = new StringBuffer();
                String t = r.readLine();
                b.append(t);
                strServerResponse = b.toString().trim();
                String[] des = CommonUtil.strServerResponse(strServerResponse);
                b.delete(0, b.length());
                if (ConnectionConstants.RES_NOT_EXIST_ACCOUNT.equals(des[0])) {
                    // = 0: show toast with message account is not exist
                    Message msg = toastHandler.obtainMessage(0);
                    toastHandler.sendMessage(msg);
                } else if (ConnectionConstants.RES_WRONG_PASSWORD.equals(des[0])) {
                    // = 1: show toast with message wrong password
                    Message msg = toastHandler.obtainMessage(1);
                    toastHandler.sendMessage(msg);
                } else if (ConnectionConstants.RES_SIGNED_IN.equals(des[0])) {
                    Message msg = toastHandler.obtainMessage(2);
                    toastHandler.sendMessage(msg);
                    JSONObject jsonUserInfo = CommonUtil.convertToJSONObject(des[1].subSequence(1, des[1].length()-1).toString());
                    //MyApplication.SOCKET_CURRENT = socket;
                    MyApplication.OS_CURRENT = os;
                    MyApplication.IS_CURRENT = is;
                    // set info to current user
                    MyApplication.USER_CURRENT = new User();
                    MyApplication.USER_CURRENT.setId(Integer.parseInt(jsonUserInfo.getString("id").toString()));
                    MyApplication.USER_CURRENT.setFullName(jsonUserInfo.getString("full_name").toString());
                    MyApplication.USER_CURRENT.setEmail(jsonUserInfo.getString("email").toString());
                    MyApplication.USER_CURRENT.setPassword(jsonUserInfo.getString("password").toString());
                    MyApplication.USER_CURRENT.setBirthday(CommonUtil.dateToString(jsonUserInfo.getString("birthday").toString()));
                    MyApplication.USER_CURRENT.setGender(Integer.parseInt(jsonUserInfo.getString("gender").toString()));
                    MyApplication.USER_CURRENT.setStatus(jsonUserInfo.getString("status"));
                    MyApplication.USER_CURRENT.setLastStatus(jsonUserInfo.getString("last_status"));
                    // set list friends to global variable in MyApplication
                    MyApplication.LIST_FRIENDS = new ArrayList<User>();
                    List<JSONObject> jsonListFriends = CommonUtil.convertToListJSONObject(des[2]);
                    for (JSONObject json : jsonListFriends) {
                        try {
                            User user = new User();
                            user.setId(json.getInt("id"));
                            user.setEmail(json.getString("email"));
                            user.setAvatar("http://profile.ak.fbcdn.net/hprofile-ak-ash3/c72.31.388.388/s160x160/69242_445766122158689_209300158_n.jpg");
                            user.setFullName(json.getString("full_name"));
                            user.setGender(json.getInt("gender"));
                            user.setBirthday(json.getString("birthday"));
                            user.setStatus(json.getString("status"));
                            user.setLastStatus(json.getString("last_status"));
                            MyApplication.LIST_FRIENDS.add(user);
                        } catch (JSONException e) {
                            Log.d("VuVT-JSONException", e.getClass().getSimpleName() + ": " + e.getMessage());
                            e.printStackTrace();
                        }
                    }
                    // set list friends request to global variable in MyApplication
                    // if have list friend request
                    if(!"".equals(des[3])) {
                        MyApplication.LIST_FRIENDS_REQUEST = new ArrayList<User>();
                        List<JSONObject> jsonListFriendsRequest = CommonUtil.convertToListJSONObject(des[3]);
                        for (JSONObject json : jsonListFriendsRequest) {
                            try {
                                User user = new User();
                                user.setId(json.getInt("id"));
                                user.setEmail(json.getString("email"));
                                user.setAvatar("http://profile.ak.fbcdn.net/hprofile-ak-ash3/c72.31.388.388/s160x160/69242_445766122158689_209300158_n.jpg");
                                user.setFullName(json.getString("full_name"));
                                user.setGender(json.getInt("gender"));
                                user.setBirthday(json.getString("birthday"));
                                user.setStatus(json.getString("status"));
                                user.setLastStatus(json.getString("last_status"));
                                MyApplication.LIST_FRIENDS_REQUEST.add(user);
                            } catch (JSONException e) {
                                Log.d("VuVT-JSONException", e.getClass().getSimpleName() + ": " + e.getMessage());
                                e.printStackTrace();
                            }
                        }
                    }
                    // set list message offline to global variable in MyApplication
                    // if have list message offline
                    if (!"".equals(des[4])) {
                        MyApplication.LIST_MESSAGE_OFFLINE = new ArrayList<MyMessage>();
                        List<JSONObject> jsonListMsg = CommonUtil.convertToListJSONObject(des[4]);
                        int id = -1; //id of user send message
                        int position = -1; //position of list message
                        MyMessage myMsg = null;
                        List<String> listMsg = null;
                        List<String> listTime = null;
                        for (JSONObject json : jsonListMsg) {
                            try {
                                if(id != json.getInt("id")) {
                                    position ++;
                                    myMsg = new MyMessage();
                                    id = json.getInt("id");
                                    myMsg.setIdGroup(id);
                                    myMsg.setNameSender(json.getString("full_name"));
                                    myMsg.setAvatarSender(json.getString("avatar"));
                                    listTime = new ArrayList<String>();
                                    listTime.add(json.getString("send_date"));
                                    myMsg.setTime(listTime);
                                    listMsg = new ArrayList<String>();
                                    listMsg.add(json.getString("msg"));
                                    myMsg.setMessage(listMsg);
                                    MyApplication.LIST_MESSAGE_OFFLINE.add(myMsg);
                                } else {
                                    listTime.add(json.getString("send_date"));
                                    myMsg.setTime(listTime);
                                    listMsg.add(json.getString("msg"));
                                    myMsg.setMessage(listMsg);
                                    MyApplication.LIST_MESSAGE_OFFLINE.set(position, myMsg);
                                }
                                
                            } catch (JSONException e) {
                                Log.d("VuVT-JSONException", e.getClass().getSimpleName() + ": " + e.getMessage());
                                e.printStackTrace();
                            }
                        }
                    }
                    //remember me
                    if(cbRememberMe.isChecked()) {
                        Editor editor=sp.edit();
                        editor.putBoolean("is_remember", true);
                        editor.putInt("id", MyApplication.USER_CURRENT.getId());
                        editor.putString("full_name", MyApplication.USER_CURRENT.getFullName());
                        editor.putString("email", MyApplication.USER_CURRENT.getEmail());
                        editor.putString("password", MyApplication.USER_CURRENT.getPassword());
                        editor.putString("birthday", MyApplication.USER_CURRENT.getBirthday());
                        editor.putInt("gender", MyApplication.USER_CURRENT.getGender());
                        editor.putString("status", MyApplication.USER_CURRENT.getStatus());
                        editor.putString("last_status", MyApplication.USER_CURRENT.getLastStatus());
                        //editor.putString("list_friends", MyApplication.LIST_FRIENDS);
                        editor.commit();
                    }
                    // finish SignInActivity
                    setResult(RESULT_CANCELED);
                    finish();
                    // start MainActivity
                    Intent intentMain = new Intent();
                    intentMain.setClass(getApplicationContext(), MainActivity.class);
                    startActivity(intentMain);
                }
            } catch (JSONException e) {
                e.printStackTrace();
            } catch (IOException e) {
                Log.d("VuVT-IOException", e.getClass().getSimpleName() + ": " + e.getMessage());
            }
            super.run();
        }
    }
}
